<?php
final class XFileReader{
	protected $file = null;
	protected $handler = null;
	
	public function __construct(XFile $file){
		$this->file = $file;
		$this->handler = @fopen($file->getPath(), 'r');
		if($this->handler
			&& !@flock($this->handler, LOCK_SH)){
			@fclose($this->handler);
			$this->handler = null;
		}
		register_shutdown_function(array($this, 'close'));
	}
	
	public function close(){
		if($this->ready()){
			@flock($this->handler, LOCK_UN);
			@fclose($this->handler);
			$this->handler = null;
		}
	}
	
	public function read($start, $length){
		if(!$this->ready()){
			return null;
		}
		$position = $this->position();
		$this->setPosition($start);
		$content = fread($this->handler, $length);
		$this->setPosition($position);
		return $content;
	}
	
	public function readByte(){
		if(!$this->ready()){
			return null;
		}
		return fread($this->handler, 1);
	}
	
	public function readChar(){
		if(!$this->ready()){
			return null;
		}
		return fgetc($this->handler);
	}
	
	public function readLine(){
		if(!$this->ready()){
			return null;
		}
		return fgets($this->handler);
	}
	
	public function readAll(){
		if(!$this->ready()){
			return null;
		}
		return file_get_contents($this->file->getPath());
	}
	
	public function ready(){
		return !is_null($this->handler) && $this->handler !== false;
	}
	
	public function reset(){
		if(!$this->ready()){
			return false;
		}
		return @rewind($this->handler);
	}
	
	public function skip($length){
		if(!$this->ready()){
			return false;
		}
		return @fseek($this->handler, $length, SEEK_CUR);
	}
	
	public function position(){
		if(!$this->ready()){
			return false;
		}
		return ftell($this->handler);
	}
	
	public function setPosition($position){
		if(!$this->ready()){
			return false;
		}
		return @fseek($this->handler, $position, SEEK_SET);
	}
}
?>